package hd

import (
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"net/url"
	"strings"
	"time"
)

type ResPPartnerAccessTokenContext struct {
	AccessToken     string    `json:"access_token"`
	RefreshToken    string    `json:"refresh_token"`
	TokenType       string    `json:"token_type"`
	ExpiresIn       int64     `json:"expires_in"`
	PartnerClientId string    `json:"partner_client_id"`
	Scope           string    `json:"scope"`
	IsHdOem         bool      `json:"isHdOem"`
	ValidStartTime  time.Time `json:"validStartTime"`
	ValidEndTime    time.Time `json:"validEndTime"`
	CreateTime      time.Time `json:"createTime"`
	CompanyName     string    `json:"companyName"`
	Type            int       `json:"type"`
	Authorities     []string  `json:"authorities"`
	Acct            string    `json:"acct"`
	Email           string    `json:"email"`
	ClientId        string    `json:"client_id"`
	Jti             string    `json:"jti"`
}

// GetPartnerAccessToken 获取C端的PartnerAccessToken （旧）推荐使用此方法获取
//推荐使用GetPartnerAccessToken_direct 替代
func GetPartnerAccessToken(code string) (ResPPartnerAccessTokenContext, error) {
	client := &http.Client{}
	urlValues := url.Values{}
	urlValues.Add("grant_type", "authorization_code")
	urlValues.Add("redirect_uri", RedirectUrl)
	urlValues.Add("code", code)
	req, _ := http.NewRequest("POST", AuthUrl+"/oauth/token", strings.NewReader(urlValues.Encode()))
	req.Header.Add("Authorization", GetBasicAuth(ClientId, ClientSecret))
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	resp, _ := client.Do(req)
	defer func(Body io.ReadCloser) {
		err := Body.Close()
		if err != nil {
			fmt.Println("close err")
		}
	}(resp.Body)
	body, _ := ioutil.ReadAll(resp.Body)
	//	fmt.Println("原返回："+string(body))
	var token = ResPPartnerAccessTokenContext{}
	err := json.Unmarshal(body, &token)
	if err != nil {
		fmt.Println("tokeErr", err)
		return token, err
	}
	return token, nil
}

// GetPartnerAccessTokenDirect 直接的方式获取C端的PartnerAccessToken 推荐使用
func GetPartnerAccessTokenDirect(authUid, authUidExtra, authUidName, authUidHead string) (ResPPartnerAccessTokenContext, error) {
	client := &http.Client{}
	urlValues := url.Values{}
	urlValues.Add("grant_type", "authorization_direct")
	urlValues.Add("auth_uid", authUid)
	urlValues.Add("auth_uid_extra", authUidExtra)
	urlValues.Add("auth_uid_name", authUidName)
	urlValues.Add("auth_uid_head", authUidHead)

	req, _ := http.NewRequest("POST", AuthUrl+"/oauth/token", strings.NewReader(urlValues.Encode()))
	req.Header.Add("Authorization", GetBasicAuth(ClientId, ClientSecret))
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	resp, _ := client.Do(req)
	defer func(Body io.ReadCloser) {
		err := Body.Close()
		if err != nil {
			fmt.Println("close err")
		}
	}(resp.Body)
	body, _ := ioutil.ReadAll(resp.Body)
	//	fmt.Println("原返回："+string(body))
	var token = ResPPartnerAccessTokenContext{}
	err := json.Unmarshal(body, &token)
	if err != nil {
		fmt.Println("tokeErr", err)
		return token, err
	}
	return token, nil
}

// GetCode 获取code
func GetCode(state, auth_uid, auth_uid_extra, auth_uid_name, auth_uid_head string) (string, error) {
	client := &http.Client{}
	params := url.Values{}
	reqUrl, err := url.Parse(AuthUrl + "/oauth/authorize")
	if err != nil {
		return "", err
	}
	params.Set("client_id", ClientId)
	params.Set("redirect_uri", RedirectUrl)
	params.Set("response_type", "code")
	params.Set("scope", "all")
	params.Set("state", state)
	params.Set("auth_uid", auth_uid)
	params.Set("auth_uid_extra", auth_uid_extra)
	params.Set("auth_uid_name", auth_uid_name)
	params.Set("auth_uid_head", auth_uid_head)
	reqUrl.RawQuery = params.Encode()
	resp, _ := client.Get(reqUrl.String())
	defer func(Body io.ReadCloser) {
		err := Body.Close()
		if err != nil {
			fmt.Println("close err")
		}
	}(resp.Body)
	body, _ := ioutil.ReadAll(resp.Body)
	//	fmt.Println("原返回：" + string(body))
	return string(body), nil
}
